import axios from "axios";
// import { Base64 } from 'js-base64';
import { ElMessage, ElMessageBox } from 'element-plus'

// Axios 通用配置
// Axios 是一个基于 promise 网络请求库，作用于node.js 和浏览器中。
// 自定义的 axios 实例
// 通过 create 方法创建一个新的 axios 实例，可以设置默认配置, 这些默认配置稍后可能会被请求中的config覆盖
// 例如：设置请求的响应类型、超时时间、请求头等
// 这样可以避免在每个请求中重复配置相同的选项，提高代码的可维护性和可读性。
// 该实例可以被导入到其他文件中使用，进行网络请求。
// 例如：import axiosInstance from '@/api/header.js';
// 这样就可以使用 axiosInstance 进行网络请求了。
let instance = axios.create({
    // 可设置项参考： https://www.axios-http.cn/docs/req_config
    responseType: 'json', // 设置响应类型为json
    timeout: 10000, // 设置请求超时时间为10秒
    headers: {
        'Content-Type': 'application/json;charset=UTF-8',
        //'Authorization': `Basic ${Base64.encode('admin:admin')}` // 使用Base64编码的用户名和密码
    }
});

// http请求拦截器
// 在axios发送请求之前给每个接口携带token去后端校验身份
instance.interceptors.request.use(
    // 此处使用箭头函数，其实就是 function(config) { ... }
    // config 是请求的配置对象，可以在这里修改请求头、参数等
    // 例如：添加 token 到请求头
    config => {
        // 在发送请求之前做些什么,可以在这里添加其他请求头或处理逻辑
        // 从localStorage中获取token
        // localStorage是浏览器提供的本地存储机制，可以在客户端存储数据
        let token = localStorage.getItem('token');
        if (token) {
            config.headers['Authorization'] = `Bearer ${token}`; // 添加token到请求头
        }
        return config;
    },
    error => {
        // 请求错误处理
        // 此处是返回的Promise.reject(error)的原因, 这样可以在调用该axios实例的地方捕获到错误, 因为 reject() 返回的是一个被拒绝的Promise
        // 并进行相应的处理，比如提示用户错误信息
        console.error('请求错误:', error);
        ElMessage.error('请求错误，请稍后再试111');
        return Promise.reject(error);
    }
);

// 添加响应拦截器
instance.interceptors.response.use(
  function (response) {
    // 2xx 范围内的状态码都会触发该函数。
    // 对响应数据做点什么
    return response;
  }, 
  function (error) {
    // 超出 2xx 范围的状态码都会触发该函数。
    // 对响应错误做点什么
    // 判断错误状态码
    if (error.response) {
      // 服务器响应了一个状态码，但状态码超出了 2xx 的范围
      switch (error.response.status) {
        case 401:
          // 未授权，可能是 token 过期或无效
          ElMessageBox.alert('登录已过期，请重新登录', '提示', {
            confirmButtonText: '确定',
            type: 'warning'
          }).then(() => { // 用户点击确定后执行的操作，为什么这里使用了 then，因为 ElMessageBox.alert 返回的是一个 Promise, 所以可以链式调用
            // 清除本地存储的 token
            localStorage.removeItem('token');
            // 跳转到登录页面
            window.location.href = '/login'; // 假设登录页面的路径是 /login
          });
          break;
        case 403:
          // 禁止访问，可能是权限不足
          ElMessage.error('您没有权限访问该资源');
          break;
        case 404:
          // 资源未找到
          ElMessage.error('请求的资源未找到');
          break;
        case 500:
          // 服务器内部错误
          ElMessage.error('服务器发生错误，请稍后再试');
          break;
        default:
          // 其他错误状态码
          ElMessage.error(`请求失败，状态码: ${error.response.status}`);
      }
    } else if (error.request) {
      // 请求已发出，但没有收到响应
      ElMessage.error('请求未收到响应，请检查网络连接');
    } else {
      // 发生了其他错误
      ElMessage.error(`请求错误: ${error.message}`);
    }
    console.error('响应错误:', error);
    // 返回一个被拒绝的Promise，以便调用该axios实例的地方可以捕获到错误
    // 这样可以在调用该axios实例的地方进行相应的错误处理
    // 例如：catch(error => { ... })
    return Promise.reject(error);
  }
);

// 导出自定义的axios实例
// 这样可以在其他文件中导入并使用该axios实例进行网络请求
// 例如：import axiosInstance from '@/api/header.js';
// 这样就可以使用 axiosInstance 进行网络请求了。
export default instance;
